import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:dart_date/dart_date.dart';
import 'package:device_apps/device_apps.dart';
import 'package:external_app_launcher/external_app_launcher.dart';
import 'package:flutter/foundation.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import 'package:native_dart_package/http/request/exception/exception_handler.dart';
import 'package:native_dart_package/native_dart_package.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:yt_devops/components/event_bus_util/eventbus_util.dart';
import 'package:yt_devops/configs.dart';
import 'package:yt_devops/pages/alarm/alarm_home/alarm_home_binding.dart';
import 'package:yt_devops/pages/alarm/alarm_home/alarm_home_model.dart';
import 'package:yt_devops/pages/alarm/alarm_home/alarm_home_view.dart';
import 'package:yt_devops/pages/site/site_overview/site_overview_model.dart';
import 'package:yt_devops/resources/str_res_keys.dart';
import 'package:yt_devops/routers/router_path.dart';
import 'package:yt_devops/services/alarm/alarm_services.dart';
import 'package:yt_devops/services/device/device_sevices.dart';
import 'package:yt_devops/services/site/site_services.dart';
import 'package:yt_devops/utils/alarm_util.dart';
import 'package:yt_devops/utils/enums.dart';
import 'package:yt_devops/utils/navigate_utils.dart';
import '../../../components/log_utils.dart';

/// 站点概况
class SiteOverviewController extends GetxController {
  /// 站点列表服务
  SiteServices siteServices = Get.put(SiteServices());
  DeviceServices deviceServices = DeviceServices();

  /// 站点ID
  late int siteId;
  late String siteName;
  // 站点类型
  String? energyOptions;
  //运行天数
  int? operationDays;
  //站点当前货币
  String monetaryUnitName = '元';

  /// 告警服务
  int alarmSum = 0;
  AlarmServices alarmServices = AlarmServices();
  AlarmNumState alarmNumState = AlarmNumState();
  RefreshController refreshController = RefreshController(
    initialRefresh: false,
  );
  SiteOverviewWeather weatherModel = SiteOverviewWeather();

  /// 站点概况-光伏数据
  List<StatisticsItemModel> pvStatistics = [];

  /// 站点概况-储能数据
  List<StatisticsItemModel> essStatistics = [];

  /// 站点概况-用电负载数据
  List<StatisticsItemModel> loadStatistics = [];

  /// 站点概况-充电桩负载数据
  List<StatisticsItemModel> chargeStatistics = [];
  DeviceDataModel? deviceCountInfo;
  Timer? deviceCountRequestTimer;
  bool isMore = false; //储能向下箭头
  List<dynamic> esUnitList = [];
  bool monitorIsOpen = false;
  String androidAppName = '';
  String iosAppName = '';
  bool isFirstLoading = true;
  @override
  void onInit() {
    super.onInit();

    if (Get.arguments != null) {
      siteId = Get.arguments['id'];
      siteName = Get.arguments['siteName'];
      energyOptions = Get.arguments['energyOptions'];
      operationDays = Get.arguments['operationDays'];
      if (Get.arguments['monetaryUnitName'] != null) {
        monetaryUnitName = Get.arguments['monetaryUnitName'];
        if (monetaryUnitName == '元' || monetaryUnitName == '¥') {
          monetaryUnitName = ResKey.yuan.tr;
        }
      }

      Log.d('arguments===111==' + monetaryUnitName);
    }

    // openExternalApp('观测云', 'weixin');
    EventBusUtil.getInstance().on<ChangeMonetaryUnit>().listen((event) {
      GetStorage storage = GetStorage();
      String storeMonetaryUnitName = storage.read('monetaryUnitName') ?? '元';
      monetaryUnitName = storeMonetaryUnitName;
      if (monetaryUnitName == '元' || monetaryUnitName == '¥') {
        monetaryUnitName = ResKey.yuan.tr;
      }
      onRefresh();
    });
  }

  @override
  void onReady() {
    getAlarmsNum();
    loadWeatherData(refereshType: RefereshType.load);
    loadDeviceNum(siteId);
    deviceCountRequestTimer =
        Timer(const Duration(seconds: 10), () => loadDeviceNum(siteId));
    loadStatisData(refereshType: RefereshType.load);
    getSiteVideoMonitorInfo();
  }

  ///获取不同天气对应的svg图
  String getWeatherSvgMap(String? weather) {
    var map = {
      '晴': 'clearDay',
      '少云': 'cloudy',
      '晴间多云': 'partlyCloudyDay',
      '多云': 'overcast',
      '阴': 'overcast',
      '有风': 'windBeaufort0',
      '平静': 'cloudy',
      '微风': 'mist',
      '和风': 'mist',
      '清风': 'mist',
      '强风/劲风': 'wind',
      '疾风': 'wind',
      '大风': 'wind',
      '烈风': 'wind',
      '风暴': 'tornado',
      '狂爆风': 'hurricane',
      '飓风': 'hurricane',
      '热带风暴': 'dustWind',
      '霾': 'fogDay',
      '中度霾': 'partlyCloudyDayFog',
      '重度霾': 'fog',
      '严重霾': 'haze',
      '阵雨': 'rain',
      '雷阵雨': 'thunderstormsRain',
      '雷阵雨并伴有冰雹': 'thunderstormsRain',
      '小雨': 'partlyCloudyDayDrizzle',
      '中雨': 'partlyCloudyDayHail',
      '大雨': 'hail',
      '暴雨': 'rain',
      '大暴雨': 'rain',
      '特大暴雨': 'rain',
      '强阵雨': 'thunderstormsRain',
      '强雷阵雨': 'thunderstormsRain',
      '极端降雨': 'rain',
      '毛毛雨/细雨': 'drizzle',
      '雨': 'drizzle',
      '小雨-中雨': 'drizzle',
      '中雨-大雨': 'hail',
      '大雨-暴雨': 'hail',
      '暴雨-大暴雨': 'rain',
      '大暴雨-特大暴雨': 'rain',
      '雨雪天气': 'sleet',
      '雨夹雪': 'sleet',
      '阵雨夹雪': 'sleet',
      '冻雨': 'sleet',
      '雪': 'sleet',
      '阵雪': 'snow',
      '小雪': 'snow',
      '中雪': 'snow',
      '大雪': 'snow',
      '暴雪': 'snow',
      '小雪-中雪': 'snow',
      '中雪-大雪': 'snow',
      '大雪-暴雪': 'snow',
      '浮尘': 'fogDay',
      '扬沙': 'fogDay',
      '沙尘暴': 'dustWind',
      '强沙尘暴': 'dustWind',
      '龙卷风': 'tornado',
      '雾': 'fogDay',
      '浓雾': 'fog',
      '强浓雾': 'haze',
      '轻雾': 'fogDay',
      '大雾': 'fog',
      '特强浓雾': 'haze',
      '热': 'thermometerWarmer',
      'wind': 'wind',
      '未知': 'iconUnknow'
    };

    if (weather != null) {
      return 'assets/weather/${map[weather]}.svg';
    }
    return 'assets/weather/overcast.svg';
  }

  /// 计算告警总数
  void _computeAlarmSum() {
    alarmSum = alarmNumState.alarmNum!.toInt() +
        alarmNumState.errorNum!.toInt() +
        alarmNumState.infoNum!.toInt() +
        alarmNumState.warnNum!.toInt();
  }

  /// 获取告警数量
  void getAlarmsNum() async {
    ///站点当前告警并且告警中
    var params = {'siteId': siteId, 'isHistoryAlarm': 0, 'status': 0};
    await alarmServices.getDiffAlarmNumNew(params).then((value) {
      alarmNumState = AlarmNumState.fromMap(value);
      Log.d('alarmNumState==' + params.toString());
      _computeAlarmSum();

      update();
    }, onError: (err) {
      handleException(err);
      return false;
    });
  }

  /// 请求站点-统计数据
  Future<void> loadStatisData(
      {RefereshType refereshType = RefereshType.refresh}) async {
    Configs.httpClient.requestWithLoading(() async {
      var params = {'siteId': siteId};
      Log.d('loadStatisData开始时间==' + DateTime.now().toString());
      var data = await siteServices.getSiteStatistics(params);
      Log.d('loadStatisData结束时间==' + DateTime.now().toString());
      isFirstLoading = false;
      pvStatistics = getPvData(data);
      essStatistics = getStoredEnergyData(data);
      loadStatistics = getLoadData(data);
      chargeStatistics = getChargeData(data);
      if (energyOptions != null && energyOptions!.contains('2')) {
        //如果是储能去请求储能单元集合
        _getEsListStatistics();
      }
      update();
    }, onError: (error) {
      refreshController.loadFailed();
      showError(error.message);
      return true;
    }, showLoading: isFirstLoading);
  }

  ///请求储能单元集合
  _getEsListStatistics() async {
    var params = {'siteId': siteId};
    var data = await siteServices.getEsListStatistics(params, onError: (error) {
      showError(error.message);
      return false;
    });
    if (data != null) {
      esUnitList = data;
      update();
    }
    Log.d('_getEsListStatistics===' + data.toString());
  }

  /// @description: 下拉刷新
  /// @return {*}
  void onRefresh() {
    getAlarmsNum();
    loadWeatherData(refereshType: RefereshType.refresh);
    if (refreshController.isRefresh) {
      refreshController.refreshCompleted();
    }
    loadDeviceNum(siteId);
    loadStatisData(refereshType: RefereshType.refresh);
  }

  List<StatisticsItemModel> getPvData(Map data) {
    return [
      StatisticsItemModel(
        name: ResKey.siteOverviewDailyPower.tr,
        value: data['pvGenerateElecDay'] ?? 0.0,
        unit: 'kWh',
      ), //当日发电量
      StatisticsItemModel(
        name: ResKey.income.tr,
        value: data['pvIncomeDay'] ?? 0.0,
        unit: ResKey.yuan.tr,
      ), //当日收益

      StatisticsItemModel(
        name: ResKey.siteOverviewMonthPower.tr,
        value: data['pvGenerateElecMonth'] ?? 0.0,
        unit: 'kWh',
      ), //当月发电量
      StatisticsItemModel(
        name: ResKey.siteOverviewYearPower.tr,
        value: data['pvGenerateElecYear'] ?? 0.0,
        unit: 'kWh',
      ), //当年发电量
      StatisticsItemModel(
        name: ResKey.siteOverviewGrandTotalPower.tr,
        value: data['pvGenerateElecTotal'] ?? 0.0,
        unit: 'kWh',
      ), //累计发电量
    ];
  }

  List<StatisticsItemModel> getStoredEnergyData(Map data) {
    return [
      StatisticsItemModel(
        name: ResKey.siteOverviewDailyCharge.tr,
        value: data['essChargeElecDay'] ?? 0.0,
        unit: 'kWh',
      ), //当日充电量
      StatisticsItemModel(
        name: ResKey.siteOverviewDailyDischarge.tr,
        value: data['essDischargeElecDay'] ?? 0.0,
        unit: 'kWh',
      ), //当日放电量

      StatisticsItemModel(
        name: ResKey.siteOverviewGrandTotalChargePower.tr,
        value: data['essChargeElecTotal'] ?? 0.0,
        unit: 'kWh',
      ), //累计充电量
      StatisticsItemModel(
        name: ResKey.siteOverviewGrandTotalDischargePower.tr,
        value: data['essDischargeElecTotal'] ?? 0.0,
        unit: 'kWh',
      ), //累计放电量

      StatisticsItemModel(
        name: ResKey.yesterdayProfit.tr,
        value: data['essIncomeLastDay'] ?? 0.0,
        unit: ResKey.yuan.tr,
      ), //累计收益
      StatisticsItemModel(
        name: ResKey.siteOverviewGrandTotalProfit.tr,
        value: data['essIncomeTotal'] ?? 0.0,
        unit: ResKey.yuan.tr,
      ), //累计收益
    ];
  }

  List<StatisticsItemModel> getLoadData(Map data) {
    return [
      StatisticsItemModel(
        name: ResKey.deviceTodayElectricityConsumption.tr,
        value: data['otherLoadCharge'] ?? 0.0,
        unit: 'kWh',
      ), // 当日用电量
      StatisticsItemModel(
        name: ResKey.deviceAccumulatedElectricityConsumption.tr,
        value: data['accOtherLoadCharge'] ?? 0.0,
        unit: 'kWh',
      ), // 累计用电量
    ];
  }

  List<StatisticsItemModel> getChargeData(Map data) {
    return [
      StatisticsItemModel(
        name: 'siteMonitor.chargingPileDayCapacity'.tr,
        value: data['chargingPileCharge'] ?? 0.0,
        unit: 'kWh',
      ), //充电桩当日充电量
      StatisticsItemModel(
        name: 'siteMonitor.chargingPileCharge'.tr,
        value: data['cpDailyOrderQuantity'] ?? 0.0,
        unit: 'siteMonitor.order'.tr, //单
      ), //充电桩当日订单量

      StatisticsItemModel(
        name: 'siteMonitor.chargingPileTotalCapacity'.tr,
        value: data['accChargingPileCharge'] ?? 0.0,
        unit: 'kWh',
      ), //充电桩累计充电量
      StatisticsItemModel(
        name: 'siteMonitor.accChargingPileCharge'.tr,
        value: data['accChargingPileCharge'] ?? 0.0,
        unit: 'siteMonitor.order'.tr, //单
      ), //充电桩累计订单量

      StatisticsItemModel(
        name: 'siteMonitor.otherLoadDayPower'.tr,
        value: data['otherLoadCharge'] ?? 0.0,
        unit: 'kWh',
      ), //其他负载当日用电量
      StatisticsItemModel(
        name: 'siteMonitor.otherLoadTotalPower'.tr,
        value: data['accOtherLoadCharge'] ?? 0.0,
        unit: 'kWh',
      ) //其他负载累计用电量
    ];
  }

  /// 请求站点-天气数据
  Future<void> loadWeatherData(
      {RefereshType refereshType = RefereshType.refresh}) async {
    Configs.httpClient.requestWithLoading(() async {
      var params = {'siteId': siteId};
      var data = await siteServices.getSiteWeather(params);
      print("站点-天气数据返回==:$data");
      if (data != null) {
        weatherModel = SiteOverviewWeather.fromJson(data);
      }
      update();
    }, onError: (error) {
      refreshController.loadFailed();
      showError(error.message);
      return true;
    }, showLoading: false);
  }

  loadDeviceNum(int siteId) => Configs.httpClient.requestWithLoading(() async {
        var data =
            await deviceServices.getDeviceCountBySiteId({'siteId': siteId});
        deviceCountInfo = DeviceDataModel.fromJson(data ?? {});
        update();
      }, showLoading: false);

  /// 跳转到告警页
  void goAlarmPage() {
    AlarmUtil.fromModule = AlarmFromWhereType.currentSite.value;
    Log.d('goAlarmPage==');
    NavigateUtils.toAlarm(
        siteId: siteId, siteName: siteName, alarmPageType: AlarmPageType.site);

    // Get.toNamed(
    //   RouterPath.alarmHome,
    //   arguments: {
    //     'siteId': siteId,
    //     'siteName': siteName,
    //   },
    // );
  }

  ///打开外部app
  void openExternalApp(String androidAppName, String iosUrlScheme) async {
    Log.d('openApp==');

    if (Platform.isAndroid) {
      if (androidAppName.isEmpty) {
        showError(ResKey.appNameNotEmpty.tr);
        return;
      }
      List<Application> apps = await DeviceApps.getInstalledApplications();
      var androidPackageName = '';
      for (var element in apps) {
        if (element.appName == androidAppName) {
          androidPackageName = element.packageName;
          break;
        }
      }

      if (androidPackageName.isNotEmpty) {
        var openAppResult = await LaunchApp.openApp(
          androidPackageName: androidPackageName,
        );
        if (openAppResult == 0) {
          showError(ResKey.openFailed.tr);
        }
      } else {
        showError(ResKey.appNotInstalled.tr);
      }
    } else {
      if (iosUrlScheme.isNotEmpty) {
        final Uri url = Uri.parse('$iosUrlScheme://');
        if (!await launchUrl(url, mode: LaunchMode.externalApplication)) {
          showError(ResKey.appNotInstalled.tr);
        }
      } else {
        // showError('iosUrlScheme不能为空');
      }
    }
  }

  void jumpApp() {
    if (Platform.isAndroid) {
      openExternalApp(androidAppName, iosAppName);
    } else {
      showError(iosAppName + ResKey.jumpNotSupported.tr);
    }
  }

  @override
  void onClose() {
    deviceCountRequestTimer?.cancel();
    super.onClose();
  }

  /// 获取视频监控配置信息
  getSiteVideoMonitorInfo() async {
    var result = await siteServices.getSiteVideoMonitorInfo({'siteId': siteId},
        onError: (error) {
      handleException(error);
      return false;
    });
    if (result != null) {
      monitorIsOpen = result['monitorStatus'].toString() == '1' ? true : false;
      iosAppName =
          result['iosAppName'] != null ? result['iosAppName'].toString() : '';
      androidAppName = result['androidAppName'] != null
          ? result['androidAppName'].toString()
          : '';
    }
  }
}
